/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package application;

import analyzer.PacketAnalyzer;
import java.io.*;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.TreeMap;
import javax.swing.table.AbstractTableModel;
import javax.swing.tree.DefaultMutableTreeNode;
import jpcap.packet.Packet;

/**
 *
 * @author lbl
 */
public class dataTable extends AbstractTableModel {

    private ArrayList<PacketAnalyzer> packets;
    private Hashtable<Integer, PacketAnalyzer> show;
    private String[] columnName = {"Number", "Time", "Source", "Destination", "Protocol"};
    private String protocol;
    private String source;
    private String destination;
    private String query;
    private boolean matchcase;

    /**
     *
     */
    public dataTable() {
        packets = new ArrayList<PacketAnalyzer>();
        show = new Hashtable<Integer, PacketAnalyzer>();
    }

    /**
     *
     * @param p
     * @param num
     */
    public void addPacket(Packet p, int num) {
        PacketAnalyzer pa = new PacketAnalyzer(p, num);
        pa.analyze();
        packets.add(pa);
        if (!filtered(pa)) {
            int i = show.size();
            show.put(i, pa);
            fireTableRowsInserted(i, i);
        }
    }

    /**
     *
     * @return
     */
    public Packet[] getAllPackets() {
        Object[] pa = packets.toArray();
        Packet[] p = new Packet[pa.length];
        for (int i = 0; i < pa.length; i++) {
            p[i] = ((PacketAnalyzer) pa[i]).getPacket();
        }
        return p;
    }

    /**
     *
     * @param num
     * @return
     */
    public String getHexPacketHeader(int num) {
        PacketAnalyzer pa = show.get(num);
        return pa.getHexHeader();
    }

    /**
     *
     * @param num
     * @return
     */
    public String getHexPacketData(int num) {
        PacketAnalyzer pa = show.get(num);
        return pa.getHexData();
    }

    /**
     *
     * @param num
     * @return
     */
    public String getHexPacket(int num) {
        PacketAnalyzer pa = show.get(num);
        return pa.getHex();
    }

    /**
     *
     * @param num
     * @return
     */
    public String getASCIIPacketHeader(int num) {
        PacketAnalyzer pa = show.get(num);
        return pa.getASCIIHeader();
    }

    /**
     *
     * @param num
     * @return
     */
    public String getASCIIPacketData(int num) {
        PacketAnalyzer pa = show.get(num);
        return pa.getASCIIData();
    }

    /**
     *
     * @param num
     * @return
     */
    public String getASCIIPacket(int num) {
        PacketAnalyzer pa = show.get(num);
        return pa.getASCII();
    }

    /**
     *
     * @param num
     * @return
     */
    public DefaultMutableTreeNode getRootNode(
            int num) {
        PacketAnalyzer pa = show.get(num);
        return pa.getRootNode();
    }

    /**
     *
     */
    public void clear() {
        packets.clear();
        show.clear();
        fireTableDataChanged();
    }

    /**
     *
     * @param p
     */
    public void setProtocol(String p) {
        protocol = p;
    }

    /**
     *
     * @param s
     */
    public void setSource(String s) {
        source = s;
    }

    /**
     *
     * @param d
     */
    public void setDestination(String d) {
        destination = d;
    }

    /**
     *
     * @param q
     */
    public void setQuery(String q) {
        query = q;
    }

    /**
     *
     * @param b
     */
    public void setMatchCase(Boolean b) {
        matchcase = b;
    }

    /**
     *
     * @param pa
     * @return
     */
    public boolean filtered(PacketAnalyzer pa) {
        if (!(source == null) && !pa.getSource().equals(source)) {
            return true;
        }
        if (!(destination == null) && !pa.getDestination().equals(destination)) {
            return true;
        }
        if (!(protocol == null) && !pa.getProtocol().equals(protocol)) {
            return true;
        }
        if (!(query == null)) {
            String s = pa.getASCII();
            String q = query;
            if (!matchcase) {
                s = s.toLowerCase();
                q = q.toLowerCase();
            }
            if (s.indexOf(query) == -1) {
                return true;
            }
        }
        return false;
    }

    /**
     *
     */
    public void fireFilterChanged() {
        show.clear();
        for (int i = 0; i < packets.size(); i++) {
            PacketAnalyzer pa = packets.get(i);
            if (!filtered(pa)) {
                show.put(show.size(), pa);
            }
        }
        fireTableDataChanged();
    }

    /**
     *
     * @param file
     * @param num
     * @throws java.io.IOException
     */
    public void savePacket(String file, int num) throws IOException {
        PacketAnalyzer pa = show.get(num);
        pa.save(file);
    }

    /**
     *
     * @param file
     * @param num
     * @throws java.io.FileNotFoundException
     * @throws java.io.IOException
     */
    public void reassemblePacket(String file, int num) throws FileNotFoundException, IOException {
        PacketAnalyzer pa = show.get(num);
        if (pa.getProtocol().equals("TCP")) {
            String key = pa.getTCPSocket();
            TreeMap<Long, PacketAnalyzer> map = new TreeMap<Long, PacketAnalyzer>();
            for (PacketAnalyzer p : show.values()) {
                if (p.getTCPSocket() != null && p.getTCPSocket().equals(key)
                        && p.getData().length != 0 && p.getAckNum() == pa.getAckNum()) {
                    map.put(p.getSeqNum(), p);
                }
            }
            //筛选相同套接字, 且ACK NUM一样的数据包, 并按SEQ NUM排序.
            FileOutputStream out = new FileOutputStream(file);
            for (PacketAnalyzer p : map.values()) {
                out.write(p.getData());
            }
            //输出到文件
            out.close();
        }
    }

    public int getRowCount() {
        return show.size();
    }

    public int getColumnCount() {
        return 5;
    }

    public Object getValueAt(
            int rowIndex, int columnIndex) {
        PacketAnalyzer pa = show.get(
                rowIndex);
        switch (columnIndex) {
            case 0:
                return pa.getNum();
            case 1:
                return pa.getTime();
            case 2:
                return pa.getSource();
            case 3:
                return pa.getDestination();
            case 4:
                return pa.getProtocol();
            default:
                return "Unknown";
        }
    }

    @Override
    public String getColumnName(
            int column) {
        return columnName[column];
    }
}
